package tp.badugi.server;

import static org.junit.Assert.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;

import org.junit.Ignore;
import org.junit.Test;

public class BadugiWinnerResolverTest {

	@Test
	public void testDetermineHand() {
		List<Card> cards = new ArrayList<Card>();
		cards.add(Card.ACE_DIAMONDS);
		cards.add(Card.ACE_CLUBS);
		cards.add(Card.THREE_DIAMONDS);
		cards.add(Card.TWO_DIAMONDS);
		BadugiWinnerResolver resolver = new BadugiWinnerResolver();
		List<Card> hand = resolver.determineHand(cards);
		assertEquals(Card.ACE_CLUBS.toString(), hand.get(0).toString());
		assertEquals(Card.TWO_DIAMONDS.toString(), hand.get(1).toString());
	}
	
	@Test
	public void testCompareHand() {
		List<Card> firstHand = new ArrayList<Card>();
		firstHand.add(Card.TWO_CLUBS);
		firstHand.add(Card.FOUR_DIAMONDS);
		firstHand.add(Card.FIVE_HEARTS);
		List<Card> secondHand = new ArrayList<Card>();
		secondHand.add(Card.THREE_DIAMONDS);
		secondHand.add(Card.FOUR_CLUBS);
		secondHand.add(Card.FIVE_SPADES);
		secondHand.add(Card.KING_HEARTS);
		BadugiWinnerResolver resolver = new BadugiWinnerResolver();
		int compareResult = resolver.compareHands(firstHand, secondHand);
		assertTrue(compareResult < 0);
	}

	@Test
	public void testGetWinnersSingleWinner() {
		Player player1 = mock(Player.class);
		List<Card> player1cards = new ArrayList<Card>();
		player1cards.add(Card.ACE_DIAMONDS);
		player1cards.add(Card.TWO_CLUBS);
		player1cards.add(Card.THREE_HEARTS);
		player1cards.add(Card.SIX_SPADES);
		when(player1.getPotContribution()).thenReturn(2000L);
		when(player1.getCards()).thenReturn(player1cards);
		Player player2 = mock(Player.class);
		List<Card> player2cards = new ArrayList<Card>();
		player2cards.add(Card.ACE_DIAMONDS);
		player2cards.add(Card.TWO_CLUBS);
		player2cards.add(Card.THREE_HEARTS);
		player2cards.add(Card.FIVE_SPADES);
		when(player2.getPotContribution()).thenReturn(2000L);
		when(player2.getCards()).thenReturn(player2cards);
		long potSize = 6000;
		List<Player> remainingPlayers = new ArrayList<Player>();
		remainingPlayers.add(player1);
		remainingPlayers.add(player2);
		BadugiWinnerResolver resolver = new BadugiWinnerResolver(remainingPlayers, potSize);
		List<Player> winners = resolver.getWinners();
		assertEquals(1, winners.size());
		Player winner = winners.get(0);
		assertEquals(player2, winner);
		Map<Player, Long> potDivision = resolver.getPotDivision();
		assertEquals(potSize, (long) potDivision.get(winner));
	}
	
	@Test
	public void testGetWinnersTwoWinners() {
		// Set up
		Player player1 = mock(Player.class);
		List<Card> player1cards = new ArrayList<Card>();
		player1cards.add(Card.ACE_DIAMONDS);
		player1cards.add(Card.TWO_CLUBS);
		player1cards.add(Card.THREE_HEARTS);
		player1cards.add(Card.FOUR_SPADES);
		when(player1.getPotContribution()).thenReturn(2000L);
		when(player1.getCards()).thenReturn(player1cards);
		
		Player player2 = mock(Player.class);
		List<Card> player2cards = new ArrayList<Card>();
		player2cards.add(Card.ACE_CLUBS);
		player2cards.add(Card.TWO_DIAMONDS);
		player2cards.add(Card.THREE_SPADES);
		player2cards.add(Card.FOUR_HEARTS);
		when(player2.getPotContribution()).thenReturn(3000L);
		when(player2.getCards()).thenReturn(player2cards);
		
		Player player3 = mock(Player.class);
		List<Card> player3cards = new ArrayList<Card>();
		player3cards.add(Card.KING_DIAMONDS);
		player3cards.add(Card.KING_CLUBS);
		player3cards.add(Card.KING_HEARTS);
		player3cards.add(Card.KING_SPADES);
		when(player3.getPotContribution()).thenReturn(3000L);
		when(player3.getCards()).thenReturn(player3cards);
		
		long potSize = 10000;
		List<Player> remainingPlayers = new ArrayList<Player>();
		remainingPlayers.add(player1);
		remainingPlayers.add(player2);
		remainingPlayers.add(player3);
		
		// Act
		BadugiWinnerResolver resolver = new BadugiWinnerResolver(remainingPlayers, potSize);
		List<Player> winners = resolver.getWinners();
		
		// Verify
		assertEquals(2, winners.size());
		Player winner1 = winners.get(0);
		Player winner2 = winners.get(1);
		assertTrue(winner1 == player1 || winner1 == player2);
		assertTrue(winner2 == player1 || winner2 == player2);
		Map<Player, Long> potDivision = resolver.getPotDivision();
		assertEquals(4000L, (long) potDivision.get(winner1));
		assertEquals(6000L, (long) potDivision.get(winner2));
	}

	@Ignore
	public void testGetPotDivision() {
		fail("Not yet implemented");
	}

}
